/**
 ******************************* ICE *******************************
 * ========================================================================
 * Project:		icefeatures
 * Package:		org.ice4apps.features
 * File:		Feature.java
 * Author: 		robin
 * Date: 		Jun 15, 2010
 * Description:	
 * ========================================================================
 * 
 */

package org.ice4apps.features;

import org.ice4apps.util.Util;

public abstract class Feature {
    
    private final int id;
    
    private final String shortName;
    
    private final String fullName;
    
    protected Feature requiredFeatures[] = null;
    
    protected Feature conflictingFeatures[] = null;
    
    protected Feature dependantFeatures[] = null;
    
    /**
     * 
     */
    protected Feature (int id, String shortName, String fullName) {
        this.id = id;
        this.shortName = shortName;
        this.fullName = fullName;
    }
    
    /**
     * @return the id
     */
    public int getId () {
        return this.id;
    }

    /**
     * @return the shortName
     */
    public String getShortName () {
        return this.shortName;
    }

    /**
     * @return the fullName
     */
    public String getFullName () {
        return this.fullName;
    }

    private long manageRequiredFeatures (long flags) throws Exception {
        if (requiredFeatures != null)
            for (Feature feature : requiredFeatures)
                feature.enable (flags);
        return flags;
    }
    
    private void manageConflictingFeatures (long flags) throws Exception {
        if (conflictingFeatures != null)
            for (Feature feature : conflictingFeatures)
                if (feature.isEnabled (flags))
                    throw new Exception ();
            
    }
    
    private void manageDependantFeatures (long flags) throws Exception {
        if (dependantFeatures != null)
            for (Feature feature : dependantFeatures)
                if (feature.isEnabled (flags))
                    throw new Exception ();            
    }
    
    public long enable (long flags) throws Exception {
        manageRequiredFeatures (flags);
        manageConflictingFeatures (flags);
        return Util.setFlag (id, flags, true);
    }
    
    public long disable (long flags) throws Exception {
        manageDependantFeatures (flags);
        return Util.setFlag (id, flags, false);
    }

    /**
     * @return the enabled
     */
    public boolean isEnabled (long... flags) {
        return Util.getFlag (id, flags);
    }
}
